package com.qfxl.common.config.webMvcConfig;

import com.qfxl.common.comm.JwtToken;
import com.qfxl.common.comm.SecretKey;
import com.qfxl.common.entity.base.RestCommEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.file.Paths;
import java.security.PublicKey;
import java.util.Map;

/**
 * HandlerInterceptor(接口 是需要实现) 和 HandlerInterceptorAdapter (类 是需要继承)
 */
@Slf4j
@Component
public class TokenInterceptor implements HandlerInterceptor {

    /**
     * 在多模块中，可能存在多个不同的校验，那就可以有多个校验类
     * 使用统一的来处理
     */
    @Resource
    TokenValidationListenerProcessor tokenValidationListenerProcessor;

    @Value("${jwt.publicKey}")
    String publicKeyKeyPath;


    @Resource
    ApplicationContext applicationContext;

    @PostConstruct
    public void init() {
//        applicationContext.
        // 此方法会在类的依赖注入完成后执行
        // 你可以在这里进行操作，确保所有依赖项都已经注入完毕
//        System.out.println("tokenValidationListener has been injected: " + tokenValidationListener);
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String servletPath = request.getServletPath();
        log.info("请求地址：" + servletPath);
        //ResourceHttpRequestHandler

        // 校验之前阶段
        if (tokenValidationListenerProcessor!=null){
            tokenValidationListenerProcessor.beforeValidation(request, response, handler);
        }
        //默认不跳过
        boolean isSkip = false;
        if (handler instanceof HandlerMethod) {
            if (tokenValidationListenerProcessor != null) {
                isSkip = tokenValidationListenerProcessor.isSkipValidation(request, response, handler);
            }
            if (!isSkip) {
                String token = request.getHeader("token");
                if (StringUtils.isEmpty(token)) {
                    throw new RuntimeException(RestCommEnum.REQ_TOKEN_NO_ERROR.getMessage());
                } else {
                    PublicKey publicKey = SecretKey.loadPublicKey(Paths.get(publicKeyKeyPath));
                    Map<String, Object> stringObjectMap = JwtToken.analysisToken(token, publicKey, "userInfo");
                    if (!CollectionUtils.isEmpty(stringObjectMap)) {
                        return true;
                    } else {
                        throw new RuntimeException(RestCommEnum.REQ_TOKEN_ERROR.getMessage());
                    }
                }
            } else {
                //跳过校验token
                return true;
            }
//            NotTokenMethod annotationMethod = (NotTokenMethod) ((HandlerMethod) handler).getMethodAnnotation(NotTokenMethod.class);
//            NotTokenController annotationController = (NotTokenController) ((HandlerMethod) handler).getMethod().getDeclaringClass().getAnnotation(NotTokenController.class);
//            if (annotationMethod == null && annotationController == null) {
//                String token = request.getHeader("token");
//                if (StringUtils.isEmpty(token)) {
//                    throw new RuntimeException(RestCommEnum.REQ_TOKEN_NO_ERROR.getMessage());
//                } else {
//                    PublicKey publicKey = SecretKey.loadPublicKey(Paths.get(publicKeyKeyPath));
//                    Map<String, Object> stringObjectMap = JwtToken.analysisToken(token, publicKey, "userInfo");
//                    if (!CollectionUtils.isEmpty(stringObjectMap)) {
//                        return true;
//                    } else {
//                        throw new RuntimeException(RestCommEnum.REQ_TOKEN_ERROR.getMessage());
//                    }
//                }
//            } else {
//                return true;
//            }
        } else if (handler instanceof ResourceHttpRequestHandler) {
            /*
            原因就在于，Spring boot 2.0对静态资源也进行了拦截，当拦截器拦截到请求之后，
            但controller里并没有对应的请求时，该请求会被当成是对静态资源的请求。
            此时的handler就是 ResourceHttpRequestHandler，就会抛出上述错误。
             */
            return true;
        } else {
            return false;
        }

    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("controller 执行完了");
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }


    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("我获取到了一个返回的结果：" + response);
        System.out.println("请求结束了");
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }

}
